/**
 * 打开数据库，有则打开没有会创建后打开
 * @param {string} database 数据库名称
 */
function open(database) {
	if(!window.plus){
		return Promise.reject('非app环境,不支持sqlite');
	}
	return new Promise((resolve, reject) => {
		const isopen = isOpen(database);
		if (isopen) {
			resolve();
		} else {
			plus.sqlite.openDatabase({
				name: database,
				path: '_doc/db/' + database + '.db',
				success(e) {
					resolve(e);
				},
				fail(e) {
					reject(e);
				}
			});
		}
	});
}

/**
 * 判断数据库是否已经打开
 * @param {string} database 数据库名称
 * @return {boolean} true代表已打开
 */
function isOpen(database) {
	if(!window.plus){
		return Promise.reject('非app环境,不支持sqlite');
	}
	return plus.sqlite.isOpenDatabase({
		name: database,
		path: '_doc/db/' + database + '.db'
	})
}

/**
 * 关闭数据库
 * @param {string} database 数据库名称
 */
function close(database) {
	if(!window.plus){
		return Promise.reject('非app环境,不支持sqlite');
	}
	return new Promise((resolve, reject) => {
		plus.sqlite.closeDatabase({
			name: database,
			success(e) {
				resolve(e);
			},
			fail(e) {
				reject(e);
			}
		});
	});
}



// 自动获取链接执行

function get(database, sqlstr, failCount) {
	//console.debug(sqlstr);
	if(!window.plus){
		return Promise.reject('非app环境,不支持sqlite');
	}
	return new Promise((resolve, reject) => {
		plus.sqlite.selectSql({
			name: database,
			sql: sqlstr,
			success(e) {
				
				resolve(e);
			},
			fail(e) {
				console.error(e);
				retry({
					err:e,
					database,
					sqlstr,
					resolveObj:null,
					failCount,
					method:'get',
					resolve,
					reject
				});
			}
		});
	});
}


/**
 * 执行sql语句
 * @param {string} database 数据库名称
 * @param {string|array<string>} sqlstr sql语句，可以是字符串或者字符串数组
 */
function exec(database, sqlstr, resolveObj, failCount) {
	//console.debug(sqlstr)
	if(!window.plus){
		return Promise.reject('非app环境,不支持sqlite');
	}
	return new Promise((resolve, reject) => {
		plus.sqlite.executeSql({
			name: database,
			sql: sqlstr,
			success(e) {
				if (resolveObj) {
					resolve(resolveObj);
				} else {
					resolve(e);
				}
			},
			fail(e) {
				// console.error(e);
				retry({
					err:e,
					database,
					sqlstr,
					resolveObj,
					failCount,
					method:'exec',
					resolve,
					reject
				});
			}
		});
	});
}


const transaction = {
	// 开启事务
	begin: function(database) {
		return this.trans(database, 'begin');
	},
	// 提交事务
	commit: function() {
		return this.trans(database, 'commit');
	},
	// 回滚事务
	rollback: function() {
		return this.trans(database, 'rollback');
	},
	trans: function(database, operation, failCount) {
		if(!window.plus){
			return Promise.reject('非app环境,不支持sqlite');
		}
		return new Promise((resolve, reject) => {
			plus.sqlite.transaction({
				name: database,
				operation: operation,
				success(e) {
					resolve(true);
				},
				fail(e) {
					retry({
						err:e,
						database,
						sqlstr,
						resolveObj:null,
						failCount,
						method:'operation',
						resolve,
						reject
					});
				}
			});
		});
	}
}


function retry({
	err,
	database,
	sqlstr,
	resolveObj,
	failCount,
	method,
	resolve,
	reject
}) {
	// -1401 sqlite没有打开
	if (err.code === -1401) {
		// 失败次数，同一方法栈失败超过1次后不再重试，避免死循环
		failCount = failCount || 0;
		if (failCount === 0) {
			failCount++;
			open(database).then(db => {
				let retryPro = null;
				switch (method) {
					case 'get':
						retryPro = get(database, sqlstr, failCount);
						break;
					case 'exec':
						retryPro = exec(database, sqlstr, resolveObj, failCount);
						break;
					case 'begin':
						retryPro = transaction.trans(database, 'begin', failCount);
						break;
					case 'commit':
						retryPro = transaction.trans(database, 'commit', failCount);
						break;
					case 'rollback':
						retryPro = transaction.trans(database, 'rollback', failCount);
						break;
					default:
						reject(err);
				}

				if (retryPro) {
					retryPro.then((res) => resolve(res)).catch(error => reject(error));
				}
			});
		} else {
			reject(err);
		}
		return;
	}
	reject(err);
}

export {
	open,
	isOpen,
	close,
	exec,
	get,
	transaction
}
